/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package ichain

import (
	reqContext "context"
	"time"

	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/core"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/iam"
	commtls "git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/util/comm/tls"
	"github.com/tjfoc/gmsm/gmtls"

	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain_sdk/metrics"
	"google.golang.org/grpc"
)

type ClientContext interface {
	core.Providers
	iam.Providers
	Providers // ichain.Providers
	iam.SigningIdentity
}

// IChainProvider 创建ichain组件-inode节点、共识节点、通信模块
type IChainProvider interface {
	CreateInodeFromConfig(inodeCfg *NetworkInode) (Inode, error)
	CreateConsenserFromConfig(cfg *ConsenserConfig) (Consenser, error)
	CommManager() CommManager
	Close()
}

// ContractCall 合约调用
type ContractCall struct {
	ID string
}

// DiscoveryService 服务发现模块，负责获取inode节点 以及按条件过滤节点
type DiscoveryService interface {
	GetInodes() ([]Inode, error)
}

// LocalDiscoveryProvider
// @Description: 静态服务发现
type LocalDiscoveryProvider interface {
	CreateLocalDiscoveryService(iamID string) (DiscoveryService, error)
}

type TargetFilter interface {
	Accept(inode Inode) bool
}

type TargetSorter interface {
	Sort(inodes []Inode) []Inode
}

// CommManager 通讯接口
type CommManager interface {
	DialContext(ctx reqContext.Context, target string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
	ReleaseConn(conn *grpc.ClientConn)
}

// EndpointConfig 节点配置接口
type EndpointConfig interface {
	Timeout(TimeoutType) time.Duration
	ConsensersConfig() []ConsenserConfig
	ConsenserConfig(nameOrURL string) (*ConsenserConfig, bool, bool)
	InodesConfig(org string) ([]InodeConfig, bool)
	InodeConfig(nameOrURL string) (*InodeConfig, bool)
	NetworkConfig() *NetworkConfig
	NetworkInodes() []NetworkInode
	ChainConfig(name string) *ChainEndpointConfig
	ChainInodes(name string) []ChainInode
	ChainConsensers(name string) []ConsenserConfig
	TLSCACertPool() commtls.CertPool
	TLSClientCerts() []gmtls.Certificate
	CryptoConfigPath() string
}

// TimeoutType 超时时间类型
type TimeoutType int

const (
	// InodeConnection inode连接超时
	InodeConnection TimeoutType = iota
	// EventReg event连接超时
	EventReg
	// Query 请求合约超时
	Query
	// Execute 执行合约超时
	Execute
	// ConsenserConnection 连接共识节点超时
	ConsenserConnection
	// ConsenserResponse 共识节点回复超时
	ConsenserResponse
	// DiscoveryGreylistExpiry 灰名单
	DiscoveryGreylistExpiry
	// ConnectionIdle 关闭连接超时
	ConnectionIdle
	// CacheSweepInterval 更新缓存超时
	CacheSweepInterval
	// EventServiceIdle 关闭event超时
	EventServiceIdle
	// InodeResponse inode回复超时
	InodeResponse
	// ResMgmt 资源管理超时
	ResMgmt
	// ChainConfigRefresh 链配置更新超时
	ChainConfigRefresh
	// ChainMembershipRefresh 链成员更新超时
	ChainMembershipRefresh
	// DiscoveryConnection 服务发现连接超时
	DiscoveryConnection
	// DiscoveryResponse 服务发现回应超时
	DiscoveryResponse
	// DiscoveryServiceRefresh 服务发现更新超时
	DiscoveryServiceRefresh
	// SelectionServiceRefresh 选择背书节点更新超时
	SelectionServiceRefresh
)

// Providers sdk所有提供者的接口
type Providers interface {
	LocalDiscoveryProvider() LocalDiscoveryProvider
	ChainProvider() ChainProvider
	IChainProvider() IChainProvider
	EndpointConfig() EndpointConfig
	MetricsProvider
}

// MetricsProvider 指标统计提供者接口
type MetricsProvider interface {
	GetMetrics() *metrics.ClientMetrics
}
